/*
配置中心

功能说明：
定义配置中心的核心接口（Matcher）、单个配置文件结构（Config）及默认匹配器实现，
提供配置的检测（Has）、获取（Get）、扫描（Scan）基础能力，为上层配置管理器（Manager）提供基础类型支撑。
*/
package config

// 导入依赖包：
// - gameServer/core/value：提供value.Value类型，用于统一封装配置值（支持多类型存储与转换）
// - gameServer/errors：自定义错误包，包含配置操作相关的错误定义（如无效扫描器）
import (
	"gameServer/core/value"
	"gameServer/errors"
)

/* //* 配置中心核心文件，定义Config接口及多种配置源实现（文件配置、环境变量配置、组合配置），支持配置监听和多协程安全访问 */

// Matcher 配置匹配器接口，定义配置操作的标准契约
// 作用：抽象“按规则匹配配置”的行为，适配不同的配置查找场景（如单规则、多规则匹配）
type Matcher interface {
	// Has 检测是否存在符合匹配规则的配置
	// 返回值：bool - 存在配置返回true，不存在返回false
	Has() bool

	// Get 获取匹配规则对应的配置值，支持默认值兜底
	// 参数：params ...interface{} - 可变参数，通常传入1个默认值（配置不存在时使用）
	// 返回值：value.Value - 封装后的配置值（含实际配置值或默认值）
	Get(params ...interface{}) value.Value

	// Scan 将匹配到的配置值直接解析到目标对象（必须传指针，否则无法赋值）
	// 参数：dest interface{} - 接收配置值的目标对象（如&struct{}、&map{}）
	// 返回值：error - 解析成功返回nil，失败（如类型不匹配）返回错误
	Scan(dest interface{}) error
}

// Config 单个配置源的单个配置文件结构体，存储配置文件的元信息与解析工具
// 作用：描述一个具体配置文件的“身份信息”（路径、名称等）和“解析能力”（解码器、扫描器）
type Config struct {
	decoder  Decoder // 解码器（Decoder类型在其他文件定义）：将配置内容（[]byte）解码为对象
	scanner  Scanner // 扫描器（Scanner类型在其他文件定义）：将配置内容直接解析到目标对象
	Path     string  // 文件路径（不含文件名），例："conf/configs/"
	File     string  // 文件全称（含扩展名），例："app.yaml"
	Name     string  // 文件名称（不含扩展名），例："app"
	Format   string  // 文件格式（即扩展名），例："yaml"、"json"，用于选择对应解析工具
	Content  []byte  // 文件内容的原始字节切片，存储配置文件的二进制数据
	FullPath string  // 文件全路径（路径+文件名），例："conf/configs/app.yaml"
}

// defaultMatcher Matcher接口的默认实现，依赖配置管理器（Manager）和匹配规则（patterns）
// 作用：通过Manager查找符合patterns规则的配置，是Matcher接口的具体落地 只匹配第一个拿到的结果
type defaultMatcher struct {
	manager  *Manager // 配置管理器指针（Manager在manager.go定义）：实际存储和管理所有配置的核心
	patterns []string // 匹配规则列表，例：["app.name", "db.host"]，按顺序查找配置
}

// newMatcher 创建Matcher接口实例，返回defaultMatcher的指针（多态：接口指向实现）
// 返回值：Matcher - 配置匹配器实例，可调用Has、Get、Scan方法
func newMatcher() Matcher {
	return &defaultMatcher{} // 初始化defaultMatcher并转型为Matcher接口
}

// Has 实现Matcher接口的Has方法：检测是否存在符合patterns规则的配置
// 核心逻辑：
// 1. 若manager未初始化（nil），直接返回false（无配置可查）
// 2. 遍历所有匹配规则，调用manager的has方法检测单条规则是否存在配置
// 3. 只要有一条规则不存在配置，整体返回false；全部存在则返回true
func (m *defaultMatcher) Has() bool {
	if m.manager == nil { // 配置管理器未就绪，无法检测配置
		return false
	}
	for _, pattern := range m.patterns { // 遍历每条匹配规则
		if ok := m.manager.has(pattern); !ok { // 调用manager的has方法检测当前规则
			return ok // 一条规则不存在，整体返回false
		}
	}
	return true // 所有规则都存在，返回true
}

// Get 实现Matcher接口的Get方法：获取符合patterns规则的配置值，无匹配则返回默认值
// 核心逻辑：
// 1. 若manager未初始化，直接返回默认值
// 2. 遍历匹配规则，调用manager的get方法获取单条规则的配置值
// 3. 找到第一条存在的配置值则返回；所有规则无匹配时，用value.NewValue封装默认值返回
func (m *defaultMatcher) Get(def ...any) value.Value {
	if m.manager != nil { // 配置管理器就绪，尝试查找配置
		for _, pattern := range m.patterns { // 按顺序遍历规则（顺序即优先级）
			if val, ok := m.manager.get(pattern); ok { // 找到存在的配置值
				return val // 返回封装后的配置值
			}
		}
	}
	// 无匹配配置，返回默认值（def为可变参数，value.NewValue会处理空默认值场景）
	return value.NewValue(def...)
}

// Scan 实现Matcher接口的Scan方法：将符合规则的配置值解析到目标对象，无匹配则返回nil
// 核心逻辑：
// 1. 若manager未初始化，返回nil（无配置可扫）
// 2. 遍历匹配规则，调用manager的get方法获取配置值
// 3. 找到第一条存在的配置值，调用其Scan方法解析到dest；所有规则无匹配时返回nil
func (m *defaultMatcher) Scan(dest interface{}) error {
	if m.manager != nil { // 配置管理器就绪，尝试扫描配置
		for _, pattern := range m.patterns { // 按顺序遍历规则
			if val, ok := m.manager.get(pattern); ok { // 找到存在的配置值
				// 调用value.Value的Scan方法，将配置值解析到dest（需dest为指针）
				return val.Scan(dest)
			}
		}
	}
	return nil // 无匹配配置，返回nil（视为“无数据可扫”，非错误）
}

// Scan 为Config结构体实现Scan方法：用自身的scanner将配置内容解析到目标对象
// 作用：让单个配置文件具备“直接解析到对象”的能力，无需依赖管理器
func (c *Config) Scan(dest interface{}) error {
	if c.scanner == nil { // 扫描器未初始化（未指定解析工具），返回无效扫描器错误
		return errors.ErrInvalidScanner
	}

	// 调用扫描器执行解析：传入文件格式（Format）、原始内容（Content）、目标对象（dest）
	// 扫描器会根据Format选择对应解析逻辑（如json.Unmarshal、yaml.Unmarshal）
	return c.scanner(c.Format, c.Content, dest)
}
